import random
from paho.mqtt import client as mqtt_client
from src.util.log_util.log import logging
import threading



# 定义Broker地址，该地址可以改为你自己的broker地址或IP。
broker = 'broker.emqx.io'
# 定义Broker的端口。
# MQTT 端口号为 1883，但也可能根据配置有所不同。
port = 1883
# 主题订阅的地方，你可以自由设定自己需要订阅的主题。
topic = "/python/mqtt"
# 客户端ID设置，随机生成，区别其他客户端。
client_id = f'python-mqtt-{random.randint(0, 100)}'

# 这个主要是建立连接的时方。
def connect_mqtt() -> mqtt_client:
    # 当每次与broker连接/重新连接，此函数将被broker调用。
    def on_connect(client, userdata, flags, rc):
        if rc == 0:
            logging.debug("Connected to MQTT Broker!")
        else:
            logging.debug("Failed to connect, return code %d\n", rc)

    # 实例一个Client的对象。
    client = mqtt_client.Client(client_id)
    # 绑定on_connect 回调函数。
    client.on_connect = on_connect
    # 使用定义的Broker信息连接至Broker。
    client.connect(broker, port)
    return client

# 订阅函数，用于订阅broker消息。
def subscribe(client: mqtt_client):
    # 当且有订阅的topic有消息发布，该函数将被broker调用。
    def on_message(client, userdata, msg):
        print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")

    # 执行订阅函数， topic为你所设定好的参数。
    client.subscribe(topic)
    # 绑定on_message回调函数。
    client.on_message = on_message

# 执行流程的函数
def run():
    client = connect_mqtt()
    subscribe(client)
    # 为了防止主线程挂起，使用守护线程，主线程结束时，订阅线程也自动结束。
    t = threading.Thread(target=client.loop_forever)
    t.start()

